/*
 * 
 */
package mt.dummy;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import mt.Order;
import mt.comm.ClientComm;
import mt.comm.ClientMessage;
import mt.comm.ClientSideMessage;
import mt.comm.ServerMessage;
import mt.comm.ServerSideMessage.Type;

// TODO: Auto-generated Javadoc
/**
 * The Class ClientCommDummy.
 *
 * @author Grupo5
 */

public class ClientCommDummy implements ClientComm {

	/** The Constant PORT. */
	private static final int PORT = 6000;// check this
	
	/** The client socket in. */
	private ObjectInputStream clientSocketIn;
	
	/** The client socket out. */
	private ObjectOutputStream clientSocketOut;
	
	/** The messages. */
	public BlockingQueue<ClientMessage> messages = new LinkedBlockingQueue<ClientMessage>();
	
	/** The nickname. */
	private String nickname;
	
	/** The socket. */
	private Socket socket;
	
	/** The thread. */
	private Thread thread;

	/* (non-Javadoc)
	 * @see mt.comm.ClientComm#connect(java.lang.String, java.lang.String)
	 */
	@Override
	public void connect(String serverAddress, String nickname) {
		this.nickname = nickname;

		try {
			// init connection
			InetAddress address = InetAddress.getByName(serverAddress);
			socket = new Socket(address, PORT);

			clientSocketOut = new ObjectOutputStream(socket.getOutputStream());
			clientSocketIn = new ObjectInputStream(socket.getInputStream());
			

		} catch (UnknownHostException e) {
			System.out.println("Host cannot be found");
		} catch (IOException e) {
			System.out.println("Connection cannot be established");
		}

		// send message to to server
		ServerMessage message = new ServerMessage(Type.CONNECTED, nickname,
				null);
		sendMessage(message);

		// waiting messages from server
		thread = new Thread(new Runnable() {

			@Override
			public void run() {

				try {

					while (!thread.interrupted()) {

						// receive message from server
						try{
						ClientMessage message = (ClientMessage) clientSocketIn
								.readObject();
						addNewMesssage(message);
						} catch (IOException e) {
							System.out.println("IO Exception in client");
						}

					}
						} catch (ClassNotFoundException e) {
					System.out.println("Invalid class message received");
					disconnect();
				
						}
				System.out.println("Fim");
				
			}
		});
		thread.start();

	}


	/* (non-Javadoc)
	 * @see mt.comm.ClientComm#isConnected()
	 */
	@Override
	public boolean isConnected() {
		return socket != null;
		

	}

	/* (non-Javadoc)
	 * @see mt.comm.ClientComm#disconnect()
	 */
	@Override
	public void disconnect() {
		try {
			// send message to disconnect
			ServerMessage msg = new ServerMessage(Type.DISCONNECTED, nickname,
					null);
			sendMessage(msg);
		
			socket.close();

		} catch (IOException e) {
			System.out.println("Erro ao fechar socket cliente");
		}
	}

	/* (non-Javadoc)
	 * @see mt.comm.ClientComm#hasNextMessage()
	 */
	@Override
	public boolean hasNextMessage() {
		return !messages.isEmpty();
	}

	/* (non-Javadoc)
	 * @see mt.comm.ClientComm#getNextMessage()
	 */
	@Override
	public ClientSideMessage getNextMessage() {
		return messages.poll();

	}

	/* (non-Javadoc)
	 * @see mt.comm.ClientComm#sendOrder(mt.Order)
	 */
	@Override
	public void sendOrder(Order order) {
		ServerMessage newOrder = new ServerMessage(Type.NEW_ORDER, nickname,
				order);
		sendMessage(newOrder);
	}

	/**
	 * Send message.
	 *
	 * @param message the message
	 */
	private void sendMessage(ServerMessage message) {
		try {
			clientSocketOut.writeObject(message);
		} catch (IOException e) {
			// disconnect();
		}
	}

	/**
	 * Adds the new messsage.
	 *
	 * @param message the message
	 */
	private void addNewMesssage(ClientMessage message) {
		messages.add(message);
	}
}
